home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 24
/
Aminet 24 (1998)(GTI - Schatztruhe)[!][Apr 1998].iso
/
Aminet
/
dev
/
c
/
cpost_1_4.lha
/
ctok.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-05-09
|
17KB
|
550 lines
/*------------------------------------------------------------------
* ctok : C language tokenizer
*------------------------------------------------------------------
* 10-01-91 Patrick J. Mueller
*------------------------------------------------------------------*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "ctok.h"
/*------------------------------------------------------------------
* is a character a valid character in a C identifier
*------------------------------------------------------------------*/
#define isCsymbol(c) (isalnum(c) || ('_' == c))
/*------------------------------------------------------------------
* typedefs
*------------------------------------------------------------------*/
typedef struct
{
int eof;
char *buffer;
long bufferLen;
long bufferInd;
long fileOffs;
long line;
int unGetChar;
int unGetReady;
long tokOffs;
long tokLen;
CTokRead readFunc;
void *readInfo;
char ident[MAX_IDENT_LEN+1];
} CTokInfo;
/*-/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\-*/
/*-\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/-*/
/*------------------------------------------------------------------
* get next char from file
*------------------------------------------------------------------*/
void GetNextChar(
int *c,
CTokInfo *cti
)
{
cti->fileOffs++;
/*---------------------------------------------------------------
* check for end of file
*---------------------------------------------------------------*/
if (cti->eof)
{
*c = EOF;
return;
}
/*---------------------------------------------------------------
* check for a char in the unget holder
*---------------------------------------------------------------*/
if (cti->unGetReady)
{
cti->unGetReady = 0;
*c = cti->unGetChar;
if ('\n' == *c)
cti->line++;
return;
}
/*---------------------------------------------------------------
* see if we need to read another buffer
*---------------------------------------------------------------*/
if (cti->bufferInd == cti->bufferLen)
{
cti->bufferLen = cti->readFunc(cti->readInfo,&(cti->buffer));
cti->bufferInd = 0L;
if (0L == cti->bufferLen)
{
*c = EOF;
cti->eof = 1;
return;
}
}
/*---------------------------------------------------------------
* read character from buffer
*---------------------------------------------------------------*/
*c = cti->buffer[cti->bufferInd++];
if ('\n' == *c)
cti->line++;
return;
}
/*------------------------------------------------------------------
* put back last char from file
*------------------------------------------------------------------*/
void UnGetNextChar(
int c,
CTokInfo *cti
)
{
cti->fileOffs--;
cti->unGetChar = c;
cti->unGetReady = 1;
if ('\n' == c)
cti->line--;
}
/*-/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\-*/
/*-\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/-*/
/*------------------------------------------------------------------
* read a C character constant or string
*------------------------------------------------------------------*/
static void ReadString(
CTokInfo *cti,
int c
)
{
int stop;
/*---------------------------------------------------------------
* the character passed in is ' or ", and it is the character that
* signifies the end of the string
*---------------------------------------------------------------*/
stop = c;
/*---------------------------------------------------------------
* keep going until we hit our stop character
*---------------------------------------------------------------*/
GetNextChar(&c,cti);
while (stop != c)
{
/*------------------------------------------------------------
* for a \, inhale next character
*------------------------------------------------------------*/
if ('\\' == c)
GetNextChar(&c,cti);
/*------------------------------------------------------------
* for EOF, break
*------------------------------------------------------------*/
if (EOF == c)
break;
GetNextChar(&c,cti);
}
return;
}
/*------------------------------------------------------------------
* read a C comment
*------------------------------------------------------------------*/
static void ReadComment(
CTokInfo *cti
)
{
int c;
/*---------------------------------------------------------------
* loop until end of file (or return in middle)
*---------------------------------------------------------------*/
GetNextChar(&c,cti);
while (EOF != c)
{
/*------------------------------------------------------------
* if not *, just get next character
*------------------------------------------------------------*/
if ('*' != c)
GetNextChar(&c,cti);
/*------------------------------------------------------------
* got a * - see if next is /
*------------------------------------------------------------*/
else
{
/*---------------------------------------------------------
* if next is /, return
*---------------------------------------------------------*/
GetNextChar(&c,cti);
if ('/' == c)
return;
}
}
return;
}
/*------------------------------------------------------------------
* read a C++ style comment
*------------------------------------------------------------------*/
static void ReadCppComment(
CTokInfo *cti
)
{
int c;
/*---------------------------------------------------------------
* loop until end of line or end of file
*---------------------------------------------------------------*/
GetNextChar(&c,cti);
while ((EOF != c) && ('\n' != c))
GetNextChar(&c,cti);
UnGetNextChar(c,cti);
return;
}
/*------------------------------------------------------------------
* read an identifier
*------------------------------------------------------------------*/
static void ReadIdent(
CTokInfo *cti,
int c
)
{
int identLen;
/*---------------------------------------------------------------
* initialize length and stick first char in
*---------------------------------------------------------------*/
identLen = 0;
cti->ident[identLen++] = (char) c;
/*---------------------------------------------------------------
* while still a valid symbol character ...
*---------------------------------------------------------------*/
GetNextChar(&c,cti);
while (isCsymbol(c))
{
/*------------------------------------------------------------
* make sure we got enough room, then stick it in
*------------------------------------------------------------*/
if (identLen < MAX_IDENT_LEN)
cti->ident[identLen++] = (char) c;
GetNextChar(&c,cti);
}
/*---------------------------------------------------------------
* finish up identifier, put last character back
*---------------------------------------------------------------*/
cti->ident[identLen] = '\0';
UnGetNextChar(c,cti);
}
/*------------------------------------------------------------------
* read a number
*------------------------------------------------------------------*/
static void ReadNumber(
CTokInfo *cti,
int c
)
{
/*---------------------------------------------------------------
* while still a valid number character ...
*---------------------------------------------------------------*/
GetNextChar(&c,cti);
while (isalnum(c))
GetNextChar(&c,cti);
/*------------------------------------